package com.ykl.base.async;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.function.Consumer;
import java.util.stream.Collectors;

@Slf4j
@Component
public class ThreadPoolComp {

    ExecutorService pool = Executors.newCachedThreadPool();

    public void run(Runnable ... task){
        Arrays.stream(task).forEach(pool::submit);
    }

    public <V> void run(
            Consumer<List<Future<V>>> onFinish,
            Consumer<Throwable> onError,
            Callable<V> ... tasks){
        List<Callable<V>> ls = Arrays.stream(tasks).collect(Collectors.toList());
        try {
            List<Future<V>> rs = pool.invokeAll(ls);
            if(onFinish!=null){
                onFinish.accept(rs);
            }
        } catch (Throwable e) {
            if(onError!=null){
                onError.accept(e);
            }
        }
    }

    public void run(
            Runnable onFinish,
            Consumer<Throwable> onError, Runnable ... tasks){
        if(tasks!=null&&tasks.length>0) {
            run((List<Future<Object>> it) -> onFinish.run(),
                    onError,
                    (Callable<Object>[]) Arrays.stream(tasks).map(t -> (Callable) () -> {
                        t.run();
                        return null;
                    }).toArray());
        }
    }


}
